package ltd.nullpointer.tcp.core.serialize;

import io.netty.buffer.ByteBuf;
import ltd.nullpointer.tcp.core.message.AbstractTCPMessage;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @ClassName: MessageSerializerFactory.java
 * @Description: 消息序列化工厂
 * @author zhangweilin
 * @date 2018年1月18日 上午10:38:14
 *
 */
public class MessageSerializerFactory {
	private MessageSerializerFactory() {
	}


	private static class MessageSerializerFactoryHolder {
		private static final MessageSerializerFactory FACTORY = new MessageSerializerFactory();
	}

	public static final MessageSerializerFactory getInstance() {
		return MessageSerializerFactoryHolder.FACTORY;
	}

	private MessageSerializer defaultMessageSerializer = new DefaultMessageSerializer();

	private static Map<Class<? extends AbstractTCPMessage>, MessageSerializer> messageSerializerMap = new HashMap<>();

	static {
		// messageSerializerMap.put(NPiotTCPMessage.class, new
		// NPiotTCPMessageSerializer());
	}

	/**
	 * 外部可以注册自定义消息序列化器
	 * 
	 * @param clazz
	 * @param messageSerializer
	 */
	public void bindMessageAnalyzer(Class<? extends AbstractTCPMessage> clazz, MessageSerializer messageSerializer) {
		messageSerializerMap.put(clazz, messageSerializer);
	}

	/**
	 * 解析字节
	 * 
	 * @param abstractTCPMessage
	 * @return
	 */
	public ByteBuf serialize(AbstractTCPMessage<?> abstractTCPMessage) {
		if (null == abstractTCPMessage) {
			throw new IllegalArgumentException("abstractTCPMessage can not be null");
		}
		MessageSerializer messageSerializer = getSerialize(abstractTCPMessage);
		if (null != messageSerializer) {
			ByteBuf byteBuf = messageSerializer.serialize(abstractTCPMessage);
			return byteBuf;
		}
		throw new IllegalArgumentException("abstractTCPMessage is invalid");
	}


	/**
	 * 获取序列化器
	 * 
	 * @param abstractTCPMessage
	 * @return
	 */
	public MessageSerializer getSerialize(AbstractTCPMessage<?> abstractTCPMessage) {
		MessageSerializer messageSerializer = messageSerializerMap.get(abstractTCPMessage.getClass());
		if (null == messageSerializer) {
			messageSerializer = defaultMessageSerializer;
		}
		return messageSerializer;
	}
}
